/**
 * 
 */
package Xmlcompare;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
import java.util.Date;
import java.util.Scanner;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * @author Sadaiyandi M
 *
 */
public class BXmlCompare {

	/**
	 * @param args
	 */
		public static int i=0; 
		static String objname="TCRMAdminContEquivBObj";
		static String elementname="AdminPartyId";
		public static String path = null,choice=null;
		public static  String  temp,Dest1,Dest2,ExcludeNode;
		public static PrintWriter log=null;
		
		public static void main(String[] args)
		{
			if(args.length==2)
			  {
				ExcludeNode=null;  
			  }
			  else if(args.length==3)
			  {
				  ExcludeNode=args[2];  
			  }
			  else
			  {
				  
				  System.out.println("invalid arguments\nPlease Specify as below");
				  System.out.println("java -jar \"ETL File\" \"Expected File\" \n or ");
				  System.out.println("java -jar \"ETL File\" \"Expected File\" \"Exclusion_Node1,Exclusion_Node2\"");
				  System.exit(0);
			  }
			try{

			path=args[0].substring(0, args[0].lastIndexOf(File.separator));
			  temp=path+File.separator+"Dest1"+new Date().toString().replace(":","-");
			  Dest1=temp;
			  //System.out.println(temp);
			}
			catch(Exception e)
			{
				 path=args[0].substring(0, args[0].lastIndexOf("/"));
				System.out.println("Warning,Better specify the path in this format\n\t  \" path\\filename \" ");
				/*System.exit(0);*/
			}
			Scanner sc= new Scanner(System.in);
			System.out.println("Default Setting:\nObject Name:\t\"TCRMAdminContEquivBObj\" \nElement Name:\t \"AdminPartyId\" \n do you want to change the Specify custom Object and Element Name? \ny/n.. ");
			choice=sc.next();
			if(choice.equalsIgnoreCase("y"))
			{
				System.out.println("Alert!\n\tmake sure that Object Name and Element Name exist in the batch xml.. ");
				System.out.println("Enter the Object Name:");
				objname=sc.next();
				System.out.println("Enter the Element Name:");
				elementname=sc.next();
			}
			else
			{
				System.out.println("Starting..\n with Default Settings..");
			}
				
			int etlFileLineCount=B2x(args[0]);
			try{
			path=args[1].substring(0, args[1].lastIndexOf(File.separator));
			  temp=path+File.separator+"Dest2"+new Date().toString().replace(":","-");
			  //System.out.println(temp);
			  Dest2=temp;
		}
		catch(Exception e)
		{
			 path=args[1].substring(0, args[1].lastIndexOf("/"));
			System.out.println("Warning,Better specify the path in this format\n\t  \" path\\filename \" ");
			/*System.exit(0);*/
		}
			
			 File directory=new File(".");
			 try {
				   log = new PrintWriter(new OutputStreamWriter(
							new FileOutputStream(directory.getCanonicalPath()+"\\log_"+new Date().toString().replaceAll(":", "-")+".log",true), "UTF-8"));
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			 int expectedFileLineCount= B2x(args[1]);
			 if(etlFileLineCount!=expectedFileLineCount)
			 {
				 log.println("--File Count--\n\tEtlFilecontains :\t"+etlFileLineCount);
				 log.println("\tExpectedFilecontains :\t"+expectedFileLineCount);
				 System.out.println("--File Count--\n\tEtlFilecontains :"+etlFileLineCount);
				 System.out.println("\tExpectedFilecontains :"+expectedFileLineCount);
				 System.out.println("\nValidating Remaining available files  :");
				
				 log.println("\nValidating Remaining available files  :\n");
			 }
			  
			  
			 if(new File(Dest2).exists())
			 {
				 ListFilesUtil listFilesUtil = new ListFilesUtil();
				 try {
					listFilesUtil.listFiles(Dest2);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				 
			 }
			 log.close();
		}
		
	public static int B2x(String BatchFile) {
		// TODO Auto-generated method stub
		String filename=BatchFile;
		BufferedReader br = null;
		 int lineCount=0;
		try {
 
			String sCurrentLine;
			  new File(temp).mkdir();
			  CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
				encoder.onMalformedInput(CodingErrorAction.REPORT);
				encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
				br = new BufferedReader(new InputStreamReader(new FileInputStream(filename), "UTF8"));
			//br = new BufferedReader(new FileReader(filename));
 
			while ((sCurrentLine = br.readLine()) != null) {
				//System.out.println(sCurrentLine);
				BXmlCompare.readFile(sCurrentLine,path);lineCount++;
				
			}
 
		} catch (IOException e) {
			System.out.println("Error,Batch XML file doesnt exist :\n check the file path whether it contains any whitespace,if so specify the path like \"filepath\"");
			System.out.println(e.getMessage());
			System.exit(0);
		} finally {
			try {
				if (br != null)br.close();
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return lineCount;
	}
	
	public static void readFile(String filename,String path)
	{
		DocumentBuilder db = null;
		String Filename=null;
		try {
			db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    InputSource is = new InputSource();
	    is.setCharacterStream(new StringReader(filename));

	    try {
			Document doc = db.parse(is);
			TransformerFactory transformerFactory = 
					  TransformerFactory.newInstance();
					  Transformer transformer = null;
					try {
						transformer = transformerFactory.newTransformer();
					} catch (TransformerConfigurationException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();

					}
					
					  transformer.setOutputProperty(OutputKeys.INDENT, "yes");
					 
					  DOMSource source = new DOMSource(doc);
					  Filename=getfilename(doc,objname,elementname);
					  
					  
					 
					  
						  
						Filename=Filename.replaceAll("[\',/'-+.^:,]", "");
						
						//Filename=Filename.replaceAll("/'", "");
					
						if(new File(temp+File.separator+Filename+".xml").isFile())
						{
							//System.out.println("Already file Exist and Specify unique value for File name");
							Filename=Filename+"_"+(Math.round(Math.random()*1000));
							
						}
						System.out.println(Filename);
					   StreamResult result =  new StreamResult(new File(temp+File.separator+Filename+".xml"));
					  try {
						transformer.transform(source, result);
						System.out.println("xml no :\t"+BXmlCompare.i+"\tcreated Sucessfully");
					} catch (TransformerException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static  String getfilename(Document document,String objname,String elementname)
	{
		String name = null;
		document.getDocumentElement().normalize();
		NodeList node = document.getElementsByTagName(objname);
		/*NodeList node = document.getElementsByTagName("TCRMAdminContEquivBObj");*/
		  int i = 0;
	  
	  Node firstNode = node.item(i);
	  if(firstNode==null)
	  {
		  System.out.println("Error,Specified object doesn't exist in  line :"+(BXmlCompare.i+1)); 
		  System.exit(0);
	  }
	  if(firstNode.getNodeType()== Node.ELEMENT_NODE){
	  Element element = (Element) firstNode;
	  NodeList firstNameElemntList = element.getElementsByTagName(elementname);
	  /*NodeList firstNameElemntList = element.getElementsByTagName("AdminPartyId");*/
	  Element firstNameElement = (Element) firstNameElemntList.item(0);
	 
	  if(firstNameElement==null)
	  {
		  System.out.println("Error,Specified Element doesn't exist in  line :"+(BXmlCompare.i+1));
		  System.exit(0);				  
	  }
	  NodeList firstName = firstNameElement.getChildNodes();
	  Node n1=firstName.item(0);
	  
	 
	  try{
	  name=n1.getNodeValue();
	  
	  }
	  
	  catch(Exception e)
	  {
		  System.out.println("Error,Specified element is empty in Line: "+(BXmlCompare.i+1));
		  
		  System.exit(0);
	  }
	
	  }
	  
	  BXmlCompare.i++;
	return name ;
}
}
